/**
**********************************************************************************************************************************************************************************************************************************
* @file:	FinalC.h
* @author:	zinface
* @date:	2021年09月09日 21:50:18 星期四
* @brief:	FinalC 的一切基础：包括声明、宗旨、规则模型等体系
**********************************************************************************************************************************************************************************************************************************
**/

#ifndef __FINALC__H__
#define __FINALC__H__

#include <stdlib.h>
#include <stdbool.h>

// FinalC

// 资源获取初始化或RAII,是一个c++编程技术[1][2],结合资源的生命周期,必须获得使用前(分配的堆内存,线程的执行,打开套接字,打开文件,锁定的互斥锁,磁盘空间,数据库中存在connection-anything供应有限)一个对象的生命周期。
// RAII保证资源对任何可能访问对象的函数都是可用的(资源可用性是类不变的，消除了冗余的运行时测试)。
// 它还保证在其控制对象的生命周期结束时释放所有资源，顺序与获取的顺序相反。
// 同样，如果资源获取失败(构造函数带异常退出)，则按初始化的相反顺序释放每个完全构造的成员和基子对象获得的所有资源。
// 这利用了核心语言特性(对象生存期、范围退出、初始化顺序和堆栈展开)来消除资源泄漏并保证异常安全。
// 这种技术的另一个名称是范围绑定资源管理(scope - bound Resource Management, SBRM)，用在RAII对象的生命周期因范围退出而结束的基本用例之后。
// 具有open()/close()、lock()/unlock()或init()/copyFrom()/destroy()成员函数的类是典型的非raii类:
// 管理自己资源的c++库类遵循RAII: std::string、std::vector、std::thread和许多其他类在构造函数中获取资源(在错误时抛出异常)，在析构函数中释放资源(在析构函数中从不抛出异常)，并且不需要显式清除。
// 此外，标准库还提供了几个RAII包装器来管理用户提供的资源…......

// typedef struct _FinalScope *FinalScop;

// - FinalC Declaration Enum
#define FinalC_Enum_Define(type)        \
typedef enum type##_enum type;          \
enum type##_enum

typedef void(*FinalC_Enum_Define);


// - FinalC Declaration Object

#define FinalC_Object_Define_Of(obj, type) typedef type obj;

#define FinalC_Object_Define(obj)               \
FinalC_Object_Define_Of(obj, struct _##obj)     \
FinalC_Object_Size_Define(obj);                 \
FinalC_Object_Create_Define(obj);               \
FinalC_Object_Conv_Define(obj);                 \
struct _##obj

typedef void(*FinalC_Object_Define);

// - FinalC Convert Object

#define FinalC_Object_Conv_Define(obj)          \
obj *conv##obj(void *data)

#define FinalC_Object_Conv(obj)                 \
FinalC_Object_Conv_Define(obj){return data;}
typedef void* (*FinalC_Object_Conv_Define)(void *data);
typedef void* (*FinalC_Object_Conv)(void *data);

// - FinalC Constructer Object Funcs

// 规范指定数据集类型的函数声明
#define FinalC_Object_Func_Prefix(func, prefix) prefix##func
#define FinalC_Object_Func_Suffix(func, suffix) func##suffix

// #define FinalC_Object_Func_After(func,)

// 获取Object大小 - 定义
#define FinalC_Object_Size_Define(obj) int FinalC_Object_Func_Suffix(obj, Size)(void)
// 创建Object
#define FinalC_Object_Create_Define(obj) obj* FinalC_Object_Func_Prefix(obj, create)(void)
// 释放Object
#define FinalC_Object_Destroy_Define(obj, v) void FinalC_Object_Func_Prefix(obj, destroy)(obj *v)
// 销毁Object
#define FinalC_Object_Delete_Define(obj, v) void FinalC_Object_Func_Prefix(obj, delete)(obj *v)
// 修复Object
#define FinalC_Object_Fix_Define(obj) void FinalC_Object_Func_Prefix(obj, fix)(obj *v)

typedef void(*FinalC_Object_Func_Prefix);
typedef void(*FinalC_Object_Func_Suffix);
typedef void(*FinalC_Object_Size_Define);
typedef void(*FinalC_Object_Create_Define);
typedef void(*FinalC_Object_Destroy_Define);
typedef void(*FinalC_Object_Delete_Define);

// /////////////////////////////////////////////////////////////
// #define FinalC_Type_Object_Func_Define(type, obj, func, ...) \
//         type obj##func(##__VA_ARGS__)

// #define FinalC_Bool_Func_Define(obj, func, ...) \
//         FinalC_Type_Object_Func_Define(bool, obj, func, ##__VA_ARGS__)

// #define FinalC_Int_Func_Define(obj, func, ...) \
//         FinalC_Type_Object_Func_Define(int, obj, func, ##__VA_ARGS__)

// #define FinalC_Long_Func_Define(obj, func, ...) \
//         FinalC_Type_Object_Func_Define(long, obj, func, ##__VA_ARGS__)

// #define FinalC_Void_Func_Define(obj, func, ...) \
//         FinalC_Type_Object_Func_Define(void, obj, func, ##__VA_ARGS__)

// #define FinalC_Point_Func_Define(obj, func, ...)\
//         FinalC_Type_Object_Func_Define(void*, obj, func, ##__VA_ARGS__)

// typedef void(*FinalC_Bool_Func_Define);
// typedef void(*FinalC_Int_Func_Define);
// typedef void(*FinalC_Long_Func_Define);
// typedef void(*FinalC_Void_Func_Define);
// typedef void(*FinalC_Point_Func_Define);
// /////////////////////////////////////////////////////////////


// 基于指定值创建Object
#define FinalC_Object_Create_With_Obj_Define(obj, val)               \
        obj* create##obj##With##val(val *v)
// 基于指定值创建Object，并在之后进行 after 操作
#define FinalC_Object_Create_With_Obj_After_Define(obj, val, func)   \
        obj* create##obj##With##val##After(val *v, after##func##val after)

// #define FinalC_Object_Create_After_Define(obj, func) \
//         obj* create##obj(after##func##obj func)

// 获取Object大小 - 实现
#define FinalC_Object_Size(obj) FinalC_Object_Size_Define(obj){return sizeof(struct _##obj);} FinalC_Object_Conv(obj)
// 创建Object - 实现
#define FinalC_Object_Create(obj) FinalC_Object_Create_Define(obj){return (obj*)calloc(obj##Size(), 1);}
// 获取Object大小并创建Object - 实现
#define FinalC_Object_Create_Size(obj) FinalC_Object_Size(obj) FinalC_Object_Create(obj)
// 基于指定值类型成员数据创建Object - 实现
#define FinalC_Object_Create_With_Obj(obj, ov, val) obj* create##obj##With##val(val *v){obj* o = create##obj();o->ov=v;return o;}

// typedef void* (*FinalC_Object_Size_Define);
// typedef void* (*FinalC_Object_Create_Define);
typedef void* (*FinalC_Object_Create_With_Obj_Define);

typedef void* (*FinalC_Object_Size);
typedef void* (*FinalC_Object_Create);
typedef void* (*FinalC_Object_Create_With_Obj);
// typedef void* (*FinalC_Object_Func);

// - Constructer

// - After
#define FinalC_Object_After(obj, func)   \
        typedef void(*after##func##obj)(obj *o)
#define FinalC_Object_After_Support(obj) \
        typedef void(*after##obj)(obj *o)
// FinalC_Object_After_Support(obj)

// #define FinalC_Object_Func(obj, ret, func, args...) ret func(##args)
// - After

// 创建 Final - 无意义
#define createFinalSourceFunc(func) void* func(void *source)
#define createFinalSourceObjectFunc(func, obj) obj func(void *source)
#define createFinalSourceObjectTypeFunc(func, obj, type) obj func(type source)
// typedef void*(*FinalSourceFunc)(void *source);
// typedef void*(*createFinalSourceFunc)(void *source);


// FinalSourceFunc
// typedef struct _FinalSourceFunc {
//     void *source;
//     void *(*func)(void *source);
// } FinalSourceFunc;

// FinalC_Object(FinalSourceFunc) {
//     void *source;
//     void *(*func)(void *source);
// };

// ------------------------------------ Final Types Defined

FinalC_Object_Define_Of(fchar, char)
FinalC_Object_Define_Of(fshort, short)
FinalC_Object_Define_Of(flong, long)
FinalC_Object_Define_Of(fint, int)
FinalC_Object_Define_Of(fboolean, fint)

FinalC_Object_Define_Of(fuchar, unsigned char);
FinalC_Object_Define_Of(fushort, unsigned short);
FinalC_Object_Define_Of(fulong, unsigned long);
FinalC_Object_Define_Of(fuint, unsigned int);

FinalC_Object_Define_Of(ffloat, float)
FinalC_Object_Define_Of(fdouble, double)

FinalC_Object_Define_Of(fpointer, void *)
FinalC_Object_Define_Of(fconstpointer, const void *)


typedef void (*FinalCFunc)(fpointer data, fpointer user);
typedef void (*FinalCDestroyFunc)(fpointer data, fpointer user);
typedef void (*FinalCDeleteFunc)(fpointer data, fpointer user);
// createFinalSourceObjectTypeFunc(toUpperString, char*, char*) {
//     return source;
// }

// FinalC_Object(FinalScop) {

// };
// #define FINAL_FINALSCOPE_SIZE sizeof(struct _FinalScop)

// FinalScop createFinalScop(void*) {
//     return malloc(FINAL_FINALSCOPE_SIZE);
// }


// FinalC Type Check Define
#define ifReturn(expression, val) if (expression) return val;
#define ifContinue(expression) if (expression) continue;
typedef void(*ifReturn);
typedef void(*ifContinue);

// FinalC Macrocs 

typedef void(*FINALC_WARN_UNUSED_RESULT);

// macros
#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
#define FINALC_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
#endif


#define FINALC_WARIN_UNUSED __attribute__((unused))


// FinalC Extension
#ifndef __FINALC_KERNEL_MODULE__
//此处保留为扩展内部支持函数，预期部分为stdout/stderr[info|warning|error]
#endif //!__FINALC_KERNEL_MODULE__

// FinalC Support And Check Variables
// Support Check
#ifndef FINALC
#define FINALC
#endif //!FINALC

// Version Check
#ifndef FINALC_VERSION
#define FINALC_VERSION 1
#endif //!FINALC_VERSION

// small
#ifndef finalc
#define finalc
#endif //!finalc

#ifndef finalc_version
#define finalc_version 1
#endif //!finalc_version

#endif //!__FINALC__H__
